package com.yuyou.fn.controller;


import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.google.common.collect.Collections2;
import com.yuyou.fn.common.constant.ClassLevelEnum;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.EnumUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.platform.service.IOpenAuthService;
import com.yuyou.fn.report.entity.Charge;
import com.yuyou.fn.report.entity.MergeStudentRegDetail;
import com.yuyou.fn.report.entity.StudentRegDetail;
import com.yuyou.fn.report.service.IChargeService;
import com.yuyou.fn.report.service.IMergeStudentRegDetailService;
import com.yuyou.fn.report.service.IStudentRegDetailService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping(value="/open/api")
public class OpenApiController extends ApiBaseController {


    @Resource
    private IChargeService chargeService;

    @Resource
    private IOpenAuthService openAuthService ;

    @Resource
    private IMergeStudentRegDetailService mergeStudentRegDetailService;

    @Resource
    private IStudentRegDetailService studentRegDetailService;


    @ApiOperation("订单数据")
    @RequestMapping(value = "/orders", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String,Object> orders(@RequestParam("appId") String appId , @RequestParam("secretKey") String sign ,@RequestParam("startDate") String startDate , @RequestParam("endDate") String endDate ) throws ParseException {
        String secretKey = openAuthService.findSecretKeyForAppId(appId);

        if(!sign.toLowerCase().equals(DigestUtils.md5Hex(appId + endDate +secretKey+ startDate ).toLowerCase())){
            return newRet("0","Invalid secretKey");
        }


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = sdf.parse(startDate);
        Date end = sdf.parse(endDate);

        Example<Charge> chargeExample = Charge.createExample();
        chargeExample.createCriteria().andGreaterThan("createTime",start).andLessThan("createTime",end );

        List<Charge> charges = chargeService.findListByExample(chargeExample);


        if(charges == null ){
            Map<String, Object> ret = newRet("1", "OK");
            ret.put("datas", Collections.EMPTY_LIST);
            return ret ;
        }
        Collection<Map<String,Object>> datas  = Collections2.transform(charges,this::toOrderData);
        Map<String, Object> ret = newRet("1", "OK");
        ret.put("datas", datas );
        return ret ;
    }

    @ApiOperation("报读数据")
    @RequestMapping(value = "/regData", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String,Object> regData(@RequestParam("appId") String appId , @RequestParam("secretKey") String sign ,@RequestParam("startDate") String startDate , @RequestParam("endDate") String endDate ) throws ParseException {
        String secretKey = openAuthService.findSecretKeyForAppId(appId);

        if(!sign.toLowerCase().equals(DigestUtils.md5Hex(appId + endDate +secretKey+ startDate ).toLowerCase())){
            return newRet("0","Invalid secretKey");
        }


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = sdf.parse(startDate);
        Date end = sdf.parse(endDate);

        Example<MergeStudentRegDetail> regDetailExample = MergeStudentRegDetail.createExample();
        regDetailExample.createCriteria().andGreaterThan("createTime",start).andLessThan("createTime",end );


        List<MergeStudentRegDetail> regDetails = mergeStudentRegDetailService.findListByExample(regDetailExample);


        if(regDetails == null ){
            Map<String, Object> ret = newRet("1", "OK");
            ret.put("datas", Collections.EMPTY_LIST);
            return ret ;
        }


        Collection<Map<String,Object>> datas  = Collections2.transform(regDetails,this::toRegData);
        Map<String, Object> ret = newRet("1", "OK");
        ret.put("datas", datas );
        return ret ;
    }


    @ApiOperation("学生报读数据")
    @RequestMapping(value = "/regData2", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String,Object> regData2(@RequestParam("appId") String appId , @RequestParam("secretKey") String sign ,@RequestParam("startDate") String startDate , @RequestParam("endDate") String endDate , @RequestParam(value = "pageNo" ,defaultValue = "1") int pageNo ,@RequestParam(value = "pageSize" , defaultValue = "500") int pageSize ) throws ParseException {
        String secretKey = openAuthService.findSecretKeyForAppId(appId);

        if(!sign.toLowerCase().equals(DigestUtils.md5Hex(appId + endDate + pageNo + pageSize +secretKey+ startDate ).toLowerCase())){
            return newRet("0","Invalid secretKey");
        }

        if(pageSize > 500 ){
            return newRet("0","Max pageSize is 500");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = sdf.parse(startDate);
        Date end = sdf.parse(endDate);

        Example<Charge> chargeExample = Charge.createExample();
        chargeExample.createCriteria().andIn("busType" , Arrays.asList(0,2)).andGreaterThan("createTime",start).andLessThan("createTime",end );

        Page<Charge> page = chargeService.findPageByExample(chargeExample, pageNo, pageSize);

        List<Charge> charges = page.getRecords();

        List<Long> regIds = BeanUtils.toList(charges, "regId");

        List<StudentRegDetail> studentRegDetails = studentRegDetailService.findByIds(regIds);
        Map<Long,StudentRegDetail> studentRegDetailMaps = BeanUtils.toMap(studentRegDetails,"regId");

        List<Map<String,Object>> regDatas = new ArrayList<>(studentRegDetails.size());
        for(Charge charge : charges ){
            StudentRegDetail studentRegDetail = studentRegDetailMaps.get(charge.getRegId());
            regDatas.add(this.toRegData2(charge,studentRegDetail));
        }

        Map<String, Object> ret = newRet("1", "OK");
        ret.put("datas", regDatas );
        ret.put("totalPage", page.getPages());
        return ret ;
    }

    private final static Map<String,String> busTypeMap = new HashMap<>();
    private final static Map<String,String> payWayMap = new HashMap<>();
    private final static Map<String,String> refundWayMap = new HashMap<>();

    static {
        busTypeMap.put("0","0|报名收费");
        busTypeMap.put("2","1|退班退费");
        busTypeMap.put("3","2|众筹押金");
        busTypeMap.put("4","3|众筹退费");
        busTypeMap.put("5","4|账户提现");
        busTypeMap.put("6","5|账户充值");

        payWayMap.put("0","0|现金");
        payWayMap.put("1","1|刷卡");
        payWayMap.put("2","2|转账");
        payWayMap.put("3","3|账户");
        payWayMap.put("4","4|微信");
        payWayMap.put("5","5|支付宝");
        payWayMap.put("6","6|tms账户");

        refundWayMap.put("0" ,"5|支付宝");
        refundWayMap.put("1" ,"4|微信");
        refundWayMap.put("2" ,"0|现金");
        refundWayMap.put("3" ,"3|退账户");
        refundWayMap.put("4" ,"2|转账退费");
    }

    private Map<String,Object> toOrderData(Charge charge) {


        try{
            Map<String,Object> data = new HashMap<>();
            if(charge.getBusType() ==0 ){
                String[] chargeIds = charge.getChargeId().split("\\|");
                String[] orderIds = charge.getOrderId().split("\\|");
                data.put("orderCode",orderIds.length > 1 ? orderIds[1] : orderIds[0]);
                data.put("orderdetailCode",chargeIds[0]);
                data.put("finaPayId",chargeIds.length > 1 ? chargeIds[1] : chargeIds[0]);
            }else{
                data.put("orderCode",charge.getOrderId());
                data.put("orderdetailCode",charge.getOrderId());
            }

            String[] orderType = busTypeMap.get(String.valueOf( charge.getBusType() )).split("\\|");

            data.put("orderType",orderType[1]);
            data.put("orderTypeCode",orderType[0]);
            data.put("productCode",charge.getProductId());
            data.put("productName",charge.getProductName());
            data.put("courseCode",charge.getCourseId());
            data.put("courseName",charge.getCourseName());
            data.put("year",charge.getYear());
            data.put("gradeName",charge.getGradeName());
            data.put("gradeCode",charge.getGradeId());
            data.put("subjectName",charge.getSubjectName());
            data.put("subjectCode",charge.getSubjectId());
            data.put("periodName",charge.getPeriodName());
            data.put("periodCode",charge.getPeriodId());
            data.put("studentName",charge.getStudentName());
            data.put("studentCode",charge.getStudentNo());
            data.put("regCampusName",charge.getRegCampus());
            data.put("regCampusCode",charge.getRegCampusId());
            data.put("chargeCampusName",charge.getChargeCampus());
            data.put("chargeCampusCode",charge.getChargeCampusId());


            if(charge.getBusType() == 0 ){
                data.put("payWayCode",payWayMap.get(String.valueOf(charge.getPayWay())).split("\\|")[0]);
                data.put("payNum",charge.getPayChannelTransactionNo());
                data.put("payableAmount",charge.getPayableAmount());
                data.put("paidAmount",charge.getPaidAmount());
                data.put("discountAmount",charge.getDiscountAmount());
            }else if(charge.getBusType() == 2 ){
                data.put("payWayCode",refundWayMap.get(String.valueOf(charge.getRefundWay())).split("\\|")[0]);
                data.put("payNum",null);
                data.put("payableAmount",null);
                data.put("paidAmount",charge.getRefundAmount());
                data.put("discountAmount",null);
            }else if(charge.getBusType() == 5 ){
                data.put("payWayCode","2" );
                data.put("payNum",null);
                data.put("payableAmount",null);
                data.put("paidAmount",charge.getRefundAmount());
                data.put("discountAmount",null);
            }else if(charge.getBusType() == 6 ){
                data.put("payWayCode",payWayMap.get(String.valueOf(charge.getPayWay())).split("\\|")[0]);
                data.put("payNum",charge.getPayChannelTransactionNo());
                data.put("payableAmount",null);
                data.put("paidAmount",charge.getPaidAmount());
                data.put("discountAmount",null);
            }else{
                data.put("payWayCode",null );
                data.put("payNum",null);
                data.put("payableAmount",null);
                data.put("paidAmount",null);
                data.put("discountAmount",null);
            }

            data.put("paySuccessTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(charge.getCreateTime()));
            data.put("updateTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(charge.getUpdateTime()));
            data.put("remark",charge.getRemark());
            return data ;
        }catch (Exception e){
            e.printStackTrace();
        }

        return null ;


    }


    private Map<String,Object> toRegData(MergeStudentRegDetail mergeStudentRegDetail) {

        try{
            Map<String,Object> data = new HashMap<>();
            data.put("classNo", mergeStudentRegDetail.getClassNo());
            data.put("className", mergeStudentRegDetail.getClassName());
            data.put("productCode", mergeStudentRegDetail.getProductId());
            data.put("productName", mergeStudentRegDetail.getProductName());
            data.put("courseCode", mergeStudentRegDetail.getCourseId());
            data.put("courseName", mergeStudentRegDetail.getCourseName());
            data.put("gradeName", mergeStudentRegDetail.getGradeName());
            data.put("gradeCode", mergeStudentRegDetail.getGradeId());
            data.put("subjectName", mergeStudentRegDetail.getSubjectName());
            data.put("subjectCode", mergeStudentRegDetail.getSubjectId());
            data.put("periodName", mergeStudentRegDetail.getPeriodName());
            data.put("periodCode", mergeStudentRegDetail.getPeriodId());
            data.put("studentName", mergeStudentRegDetail.getStudentName());
            data.put("studentCode", mergeStudentRegDetail.getStudentNo());
            data.put("studentPhoneNo", mergeStudentRegDetail.getStudentPhoneNo());
            data.put("regCampusName", mergeStudentRegDetail.getCampusName());
            data.put("regCampusCode", mergeStudentRegDetail.getCampusId());
            data.put("areaTeamCode", mergeStudentRegDetail.getAreaTeamId());
            data.put("areaTeamName", mergeStudentRegDetail.getAreaTeamName());
            return data ;
        }catch (Exception e){
            e.printStackTrace();
        }

        return null ;


    }

    private Map<String,Object> toRegData2(Charge charge , StudentRegDetail studentRegDetail ) {

        try{
            Map<String,Object> data = new HashMap<>();
            data.put("regCode", charge.getRegId());//报读code
            data.put("regFrom", charge.getRegFrom());//报名来源 0：线下 1：线上
            data.put("studentRegType", studentRegDetail.getStudentState());//生源类型 0:新生 1:老生 2:续读生
            data.put("regOrderCode", studentRegDetail.getCourseOrderId());//报读订单code
            data.put("busType", charge.getBusType() == 0 ? 0 : 1 );//业务类型 0:缴费 1:退费

            data.put("classCode", charge.getClassId());//班级
            data.put("className", charge.getClassName());
            data.put("productCode",charge.getProductId());//产品
            data.put("productName",charge.getProductName());
            data.put("courseCode",charge.getCourseId());//课程
            data.put("courseName",charge.getCourseName());
            data.put("year",charge.getYear());
            data.put("gradeName",charge.getGradeName());//年级
            data.put("gradeCode",charge.getGradeId());
            data.put("subjectName",charge.getSubjectName());//科目
            data.put("subjectCode",charge.getSubjectId());
            data.put("periodName",charge.getPeriodName());//期数
            data.put("periodCode",charge.getPeriodId());
            data.put("segmentNo",studentRegDetail.getSegmentNo());//段次
            data.put("studentName",charge.getStudentName());//学生
            data.put("studentCode",charge.getStudentNo());
            data.put("studentPhoneNo",studentRegDetail.getStudentPhoneNo());
            data.put("areaTeamCode",charge.getAreaTeamId());//城市区域
            data.put("areaTeamName",charge.getAreaTeamName());
            data.put("regCampusName",charge.getRegCampus());//报读校区
            data.put("regCampusCode",charge.getRegCampusId());
            data.put("chargeCampusName",charge.getChargeCampus());//收费/退费校区
            data.put("chargeCampusCode",charge.getChargeCampusId());

            data.put("initStartLectureNo",studentRegDetail.getInitStartAmount());//初始报读开始讲次
            data.put("initEndLectureNo",studentRegDetail.getInitEndAmount());//初始报读结束讲次

            if(charge.getBusType() == 0 ){//缴费
                data.put("payableAmount",charge.getPayableAmount());//课程应该金额
                data.put("paidAmount",charge.getPaidAmount());//本次缴费金额
                data.put("discountAmount",charge.getDiscountAmount());//优惠
            }else{
                data.put("refundAmount",charge.getRefundAmount());//退费金额
                data.put("refundLectureNos",charge.getRemark().split(":")[1]);//退费讲次
            }

            data.put("createTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(charge.getCreateTime()));
            data.put("updateTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(charge.getUpdateTime()));

            return data ;
        }catch (Exception e){
            e.printStackTrace();
        }

        return null ;
    }

    private Map<String,Object> newRet(String code , String message ){

        Map<String,Object> ret = new HashMap<>();
        ret.put("code",code);
        ret.put("message",message);
        return ret ;
    }


}
